function trim(str) {
	return str.replace(/^\s+|\s+$/gm, "");
}

function getById(id) {
	return document.getElementById(id);
}

function getSelectedOptionValue(id) {
	var el = getById(id);
	var i = el.options.selectedIndex;
	return el[i].value;
}

function getNumById(id) {
	var e = getById(id);
	if (e == null) {
		return 0;
	}
	var val = e.value;
	if (val == null) {
		return 0;
	}
	val = trim(val);
	if (val == "") {
		return 0;
	}
	if (isNaN(val)) {
		return 0;
	}
	return parseInt(val);
}

var panel = {
	"shenqi" : 0,
	"anqi" : 0,
	"longwen" : 0,
	"xsxPercent" : 0,
	"danUsed" : false,
	"equipPoints" : {
		"tl" : 0,
		"sf" : 0
	},
	"equipNumbers" : {
		"xsx" : 0,
		"mz" : 0,
		"sb" : 0,
		"hx" : 0,
		"hf" : 0
	},
	"curr" : {
		"role" : "",
		"type" : "",
		"basePoints" : {
			"tl" : 0,
			"sf" : 0
		},
		"manualPoints" : {
			"tl" : 0,
			"sf" : 0
		},
		"xlPoints" : {
			"tl" : 0,
			"sf" : 0
		},
		"inputPoints" : {
			"tl" : 0,
			"sf" : 0
		},
		"inputNumbers" : {
			"xsx" : 0,
			"mz" : 0,
			"sb" : 0,
			"hx" : 0,
			"hf" : 0
		}
	},
	"target" : {
		"role" : "",
		"type" : "",
		"basePoints" : {
			"tl" : 0,
			"sf" : 0
		},
		"manualPoints" : {
			"tl" : 0,
			"sf" : 0
		},
		"xlPoints" : {
			"tl" : 0,
			"sf" : 0
		},
		"showPoints" : {
			"tl" : 0,
			"sf" : 0
		},
		"showNumbers" : {
			"xsx" : 0,
			"mz" : 0,
			"sb" : 0,
			"hx" : 0,
			"hf" : 0
		}
	}
};

function initPanel() {
	// 公共部分
	var shenqi = getNumById("shenqi");
	var anqi = getNumById("anqi");
	var longwen = getNumById("longwen");
	var xsxPercent = 1 + (shenqi + anqi + longwen) / 100;
	var danUsed = getById("danUsed").checked;
	panel.shenqi = shenqi;
	panel.anqi = anqi;
	panel.longwen = longwen;
	panel.danUsed = danUsed;
	panel.xsxPercent = xsxPercent;
	// --- 当前面板 ----
	// 当前门派、加点方式
	var currRole = getSelectedOptionValue("currRole");
	var currType = getSelectedOptionValue("currType");
	panel.curr.role = currRole;
	panel.curr.type = currType;
	// 用户输入的点数（体、身）
	var inputTLPoints = getNumById("currTL");
	var inputSFPoints = getNumById("currSF");
	panel.curr.inputPoints.tl = inputTLPoints;
	panel.curr.inputPoints.sf = inputSFPoints;
	// 用户输入的数值（血、命、闪、会心、会防）
	var inputXSXNumbers = getNumById("currXSX");
	var inputMZNumbers = getNumById("currMZ");
	var inputSBNumbers = getNumById("currSB");
	var inputHXNumbers = getNumById("currHX");
	var inputHFNumbers = getNumById("currHF");
	panel.curr.inputNumbers.xsx = inputXSXNumbers;
	panel.curr.inputNumbers.mz = inputMZNumbers;
	panel.curr.inputNumbers.sb = inputSBNumbers;
	panel.curr.inputNumbers.hx = inputHXNumbers;
	panel.curr.inputNumbers.hf = inputHFNumbers;
	// 基础点数
	var baseTLPoints = calcBasePoints(currRole, "tl");
	var baseSFPoints = calcBasePoints(currRole, "sf");
	panel.curr.basePoints.tl = baseTLPoints;
	panel.curr.basePoints.sf = baseSFPoints;
	// 手动分配点数
	var manualTLPoints = calcManualPoints(danUsed, "tl", currType);
	var manualSFPoints = calcManualPoints(danUsed, "sf", currType);
	panel.curr.manualPoints.tl = manualTLPoints;
	panel.curr.manualPoints.sf = manualSFPoints;
	// 修炼增加点数
	var xlTLPoints = calcXLPoints(baseTLPoints, manualTLPoints);
	var xlSFPoints = calcXLPoints(baseSFPoints, manualSFPoints);
	panel.curr.xlPoints.tl = xlTLPoints;
	panel.curr.xlPoints.sf = xlSFPoints;
	// 装备增加点数
	var equipTLPoints = calcEquipPoints(inputTLPoints, baseTLPoints, manualTLPoints);
	var equipSFPoints = calcEquipPoints(inputSFPoints, baseSFPoints, manualSFPoints);
	panel.equipPoints.tl = equipTLPoints;
	panel.equipPoints.sf = equipSFPoints;
	// 装备增加数值
	var equipXSXNumbers = calcEquipNumbers(currRole, inputXSXNumbers, inputTLPoints, xlTLPoints, "xsx", xsxPercent);
	var equipMZNumbers = calcEquipNumbers(currRole, inputMZNumbers, inputSFPoints, xlSFPoints, "mz", 1);
	var equipSBNumbers = calcEquipNumbers(currRole, inputSBNumbers, inputSFPoints, xlSFPoints, "sb", 1);
	var equipHXNumbers = calcEquipNumbers(currRole, inputHXNumbers, inputSFPoints, xlSFPoints, "hx", 1);
	var equipHFNumbers = calcEquipNumbers(currRole, inputHFNumbers, inputSFPoints, xlSFPoints, "hx", 1);
	panel.equipNumbers.xsx = equipXSXNumbers;
	panel.equipNumbers.mz = equipMZNumbers;
	panel.equipNumbers.sb = equipSBNumbers;
	panel.equipNumbers.hx = equipHXNumbers;
	panel.equipNumbers.hf = equipHFNumbers;
	// --- 目标面板 ----
	panel.target.role = getSelectedOptionValue("targetRole");
	panel.target.type = getSelectedOptionValue("targetType");
}

function calcTarget() {
	var targetRole = panel.target.role;
	var targetType = panel.target.type;
	var danUsed = panel.danUsed;
	var xsxPercent = panel.xsxPercent;
	// 基础点数
	var baseTLPoints = calcBasePoints(targetRole, "tl");
	var baseSFPoints = calcBasePoints(targetRole, "sf");
	panel.target.basePoints.tl = baseTLPoints;
	panel.target.basePoints.sf = baseSFPoints;
	// 手动分配点数
	var manualTLPoints = calcManualPoints(danUsed, "tl", targetType);
	var manualSFPoints = calcManualPoints(danUsed, "sf", targetType);
	panel.target.manualPoints.tl = manualTLPoints;
	panel.target.manualPoints.sf = manualSFPoints;
	// 修炼增加点数
	var xlTLPoints = calcXLPoints(baseTLPoints, manualTLPoints);
	var xlSFPoints = calcXLPoints(baseSFPoints, manualSFPoints);
	panel.target.xlPoints.tl = xlTLPoints;
	panel.target.xlPoints.sf = xlSFPoints;
	// 装备增加点数
	var equipTLPoints = panel.equipPoints.tl;
	var equipSFPoints = panel.equipPoints.sf;
	// 显示点数
	var showTLPoints = baseTLPoints + manualTLPoints + equipTLPoints;
	var showSFPoints = baseSFPoints + manualSFPoints + equipSFPoints;
	panel.target.showPoints.tl = showTLPoints;
	panel.target.showPoints.sf = showSFPoints;
	// 显示数值
	var equipXSXNumbers = panel.equipNumbers.xsx;
	var equipMZNumbers = panel.equipNumbers.mz;
	var equipSBNumbers = panel.equipNumbers.sb;
	var equipHXNumbers = panel.equipNumbers.hx;
	var equipHFNumbers = panel.equipNumbers.hf;
	var sumTLPoints = showTLPoints + xlTLPoints;
	var sumSFPoints = showSFPoints + xlSFPoints;
	var showXSXNumbers = calcShowNumbers(targetRole, "xsx", sumTLPoints, xsxPercent, equipXSXNumbers);
	var showMZNumbers = calcShowNumbers(targetRole, "mz", sumSFPoints, 1, equipMZNumbers);
	var showSBNumbers = calcShowNumbers(targetRole, "sb", sumSFPoints, 1, equipSBNumbers);
	var showHXNumbers = calcShowNumbers(targetRole, "hx", sumSFPoints, 1, equipHXNumbers);
	var showHFNumbers = calcShowNumbers(targetRole, "hx", sumSFPoints, 1, equipHFNumbers);
	panel.target.showNumbers.xsx = showXSXNumbers;
	panel.target.showNumbers.mz = showMZNumbers;
	panel.target.showNumbers.sb = showSBNumbers;
	panel.target.showNumbers.hx = showHXNumbers;
	panel.target.showNumbers.hf = showHFNumbers;
}

function showPanel() {
	getById("targetTL").value = panel.target.showPoints.tl;
	getById("targetSF").value = panel.target.showPoints.sf;
	getById("targetXSX").value = panel.target.showNumbers.xsx;
	getById("targetMZ").value = panel.target.showNumbers.mz;
	getById("targetSB").value = panel.target.showNumbers.sb;
	getById("targetHX").value = panel.target.showNumbers.hx;
	getById("targetHF").value = panel.target.showNumbers.hf;
}

function calc() {
	initPanel();
	calcTarget();
	showPanel();
}

// 获取门派属性成长率
function getRolePropRatio(role, prop) {
	var ratioProp = ratioPropData[role];
	return ratioProp[prop];
}

// 计算：10级裸属性 + 升级时自动增加的属性，结果四舍五入
function calcBasePoints(role, attr) {
	// 10级裸属性
	var baseAttrs = baseAttrData[role];
	var basePoints = baseAttrs[attr];
	// 升级时自动增加的属性
	var lvlAttrs = lvlAttrData[role];
	var lvlAttrVal = lvlAttrs[attr];
	var lvlSumPoints = lvlAttrVal * 109; // 119-10级
	var result = 0;
	if (role == "mr" || role == "gg") { // 慕容、鬼谷，向下取整
		result = Math.floor(basePoints + lvlSumPoints);
	} else { // 其他门派，四舍五入
		result = Math.round(basePoints + lvlSumPoints);
	}
	return result;
}

// 计算：10级裸血上限 + 升级时自动增加的血上限
function calcBaseXsxNumber(role) {
	var base = baseAttrData[role];
	var lvl = lvlAttrData[role];
	return base.xsx + lvl.xsx * 109;
}

// 计算：升级时手动分配的属性 + 潜能丹增加的属性
function calcManualPoints(danUsed, attr, type) {
	// 升级时手动分配的属性
	var manualPoints = 0;
	if (attr == type) {
		manualPoints = 240;
	}
	// 潜能丹增加的属性
	var danPoints = 0;
	if (danUsed && attr == type) {
		danPoints = 70;
	}
	return manualPoints + danPoints;
}

// 计算：修炼增加的属性，结果向上取整
function calcXLPoints(basePoints, manualPoints) {
	var result = (basePoints + manualPoints) * 1.7511;
	return Math.ceil(result.toFixed(2));
}

// 计算：装备增加的点数
function calcEquipPoints(inputPoints, basePoints, manualPoints) {
	return inputPoints - basePoints - manualPoints;
}

// 计算：装备增加的数值
function calcEquipNumbers(role, inputNumbers, inputPoints, xlPoints, prop, percent) {
	var ratio = getRolePropRatio(role, prop);
	var baseXsxNumber = 0;
	if (prop == "xsx") { // 当计算血上限时，需要扣掉10级裸血上限 + 升级时自动增加的血上限
		baseXsxNumber = calcBaseXsxNumber(role);
	}
	return Math.ceil(inputNumbers - (inputPoints + xlPoints) * ratio * percent - baseXsxNumber * percent);
}

// 计算：目标面板显示数值
function calcShowNumbers(role, prop, sumPoints, percent, equipNumbers) {
	var ratio = getRolePropRatio(role, prop);
	var baseXsxNumber = 0;
	if (prop == "xsx") { // 当计算血上限时，需要加上10级裸血上限 + 升级时自动增加的血上限
		baseXsxNumber = calcBaseXsxNumber(role);
	}
	return Math.ceil(sumPoints * ratio * percent + equipNumbers + baseXsxNumber * percent);
}
